package com.itheima.d4_byte_stream;

import java.io.*;

/**
 * 目标：使用文件字节输入流一次读取完文件的全部字节。
 *
 * 方式一：自己定义一个字节数组与被读取的文件大小一样大，然后使用该字节数组，一次读完文件的全部字节。
 *      public int read(byte[] buffer)  每次用一个字节数组去读取，返回字节数组读取了多少个字节，如果发现没有数据可读会返回-1.
 * 方式二：Java官方为InputStream提供了如下方法，可以直接把文件的全部字节读取到一个字节数组中返回。
 *      public byte[] readAllBytes() throws IOException     直接将当前字节输入流对应的文件对象的字节数据装到一个字节数组返回
 *
 *1.如何使用字节输入流读取中文内容输出时不乱码呢？
 * 一次性读取完全部字节。
 * 可以定义与文件一样大的字节数组读取，也可以使用官方API.
 *2.直接把文件数据全部读取到一个字节数组可以避免乱码，是否存在问题？
 * 如果文件过大，定义的字节数组可能引起内存溢出。
 *
 *  读写文本内容更适合用“字符流”
 *  字节流适合做数据的转移，如文件复制等
 */
public class FileInputStreamTest3 {
    public static void main(String[] args) throws Exception {
        // 1、一次性读取完文件的全部字节到一个字节数组中去。
        // 创建一个字节输入流管道与源文件接通
        InputStream is = new FileInputStream("Day08File-Io-App\\src\\itheima03.txt");

        // 2、准备一个字节数组，大小与文件的大小正好一样大。
        File f = new File("Day08File-Io-App\\src\\itheima03.txt");
        long size = f.length();     //获取文件大小
        //定义和文件大小一样大的字节数组
        byte[] buffer = new byte[(int) size];
        //要求强制转换也看得出来这种读取文件的局限性，文件大小返回的值由long类型变量接收，但是字节数组范围远小于 long类型长度

        int len = is.read(buffer);
        System.out.println(new String(buffer));

        System.out.println("文件大小： "+size);
        System.out.println("每次读取的字节大小： "+len);

        //弹幕：这个方法是 JDK 9 以上的版本才支持 ，不然会爆红！
        /* 源码：
         if (MAX_BUFFER_SIZE - total < nread) {
                    throw new OutOfMemoryError("Required array size too large");
                }
                sun公司也有考虑到文件长度大于内存长度的情况，不会创建字节数组，会直接抛异常
         */
        System.out.println("---------------------整套视频已学完，回过头来自己试一试-------------------");
        InputStream zeng1 = new FileInputStream("Day08File-Io-App\\src\\itheima01.txt");
        byte[] zeng1bytes = zeng1.readAllBytes();
        System.out.println(new String(zeng1bytes));

        zeng1.close();

        is.close(); // 关闭流
    }
}
